#include "clamp.h"
#include "crate.h"
#include "../framework.h"
#include <iostream>

Vertexf Clamp::vertices[] = { 	Vertexf(-0.5f,-0.25f),Vertexf(0.5f,-0.25f),
								Vertexf(0.25f,0.25f),Vertexf(-0.25f,0.25f)};

const float Clamp::rotationSpeed =  0.05f;
const float Clamp::maxRotationAngle =  0.456;

Clamp::Clamp(Rectangle rec)
	: 	SceneObject(rec),
		Grabber(Rectangle(rec.centerX(),rec.centerX(),rec.centerY(),rec.centerY())){
	this->objVertices.vertices = vertices;
	this->objVertices.nVertices = nVertices;
	this->state = Clamp::OPEN;

	this->addObject(ClampSide::name(),new ClampSide());
}

Clamp::~Clamp(){
}

void Clamp::draw(){
	Framework& fr = Framework::instance();

	Colorf old = fr.pipeline.getFillColor();
	fr.pipeline.pushMatrix();
		fr.pipeline.setFillColor(Colorf(0.77f,0.78f,0.77f));
		fr.pipeline.translate(this->dimensions.centerX(),this->dimensions.centerY());
		fr.pipeline.escale(this->dimensions.width(),this->dimensions.height());

		fr.pipeline.setFillColor(Colorf(0.0f,0.0f,0.0f));
		fr.pipeline.draw(Pipeline::POLYGON,objVertices.vertices,objVertices.nVertices);

		fr.pipeline.pushMatrix();
			fr.pipeline.setFillColor(Colorf(0.77f,0.78f,0.77f));
			fr.pipeline.escale(0.8f,0.8f);
			fr.pipeline.draw(Pipeline::POLYGON,objVertices.vertices,objVertices.nVertices);
		fr.pipeline.popMatrix();

		fr.pipeline.setFillColor(Colorf(0.77f,0.78f,0.77f));
		this->findObject(ClampSide::name()).draw();

		fr.pipeline.escale(-1.0f,1.0f);
		this->findObject(ClampSide::name()).draw();
	fr.pipeline.popMatrix();
	fr.pipeline.setFillColor(old);

	if(this->getGrabbed()){
		this->findObject(Grabable::name()).draw();
	}
}

void Clamp::move(float dx,float dy){
	SceneObject::move(dx,dy);
	this->movePosition(dx,dy);
	if(this->getGrabbed()){
		this->findObject(Grabable::name()).move(dx,dy);
	}
}

void Clamp::addObject(const std::string& name,SceneObject* obj){
	SceneObject::addObject(name,obj);
	obj->getDimensions().center(this->dimensions.centerX(),this->dimensions.centerY()+this->dimensions.height()/2);
}

void Clamp::open(){
	if(this->state==Clamp::CLOSING || this->state==Clamp::CLOSED)
		this->state=Clamp::OPENING;
}

void Clamp::close(){
	if(this->state==Clamp::OPENING || this->state==Clamp::OPEN)
		this->state=Clamp::CLOSING;
}

bool Clamp::isOpen(){
	return this->state==Clamp::OPEN;
}

bool Clamp::isClosed(){
	return this->state==Clamp::CLOSED;
}

void Clamp::timeStep(){
	ClampSide& side = dynamic_cast<ClampSide&>(this->findObject(ClampSide::name()));

	if(this->state==Clamp::CLOSING){
		if(side.getRotationAngle()>=Clamp::maxRotationAngle){
			this->state = Clamp::CLOSED;
			side.setRotationAngle(Clamp::maxRotationAngle);
			this->grab();
			if(this->getGrabbed()){
				Crate* grabbed = static_cast<Crate*>(this->getGrabbed());
				this->addObject(Grabable::name(),grabbed);
			}else{
				this->state = Clamp::OPENING;
			}
		}else{
			side.addRotationAngle(Clamp::rotationSpeed);
		}
	}else if(this->state==Clamp::OPENING){
		if(side.getRotationAngle()<=0){
			this->state = Clamp::OPEN;
			side.setRotationAngle(0);
		}else{
			side.addRotationAngle(-1.0f*Clamp::rotationSpeed);
		}
	}
}
